package org.wxd.sign.filter;


import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.wxd.sign.annotation.SignApi;
import org.wxd.sign.utils.SignUtils;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@NoArgsConstructor
@Slf4j
public class RequestSignFilter implements Filter {

    RequestMappingHandlerMapping mapping;

    public RequestSignFilter(RequestMappingHandlerMapping mapping) {
        this.mapping = mapping;
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    private HandlerMethod findHandlerMethod(HttpServletRequest request) {
        try {
            HandlerExecutionChain executionChain = mapping.getHandler(request);
            if (Objects.isNull(executionChain)) return null;
            return (HandlerMethod) executionChain.getHandler();
        } catch (Exception e) {
        }
        return null;

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        // josn 文件上传 放行
        if (isJsonReq(request)) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }

        // 获取handler
        HandlerMethod handlerMethod = findHandlerMethod(request);
        if (Objects.isNull(handlerMethod)) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        } else {
            handlerMethod.getMethod();
        }
        // 获取注解
        SignApi signConf = handlerMethod.getMethod().getAnnotation(SignApi.class);
        if (!SignUtils.isSignInput(signConf)) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }
        // 入参 处理
        Map<String, String> codeSignMap = findInputCodeSignMap(request);

        if (SignUtils.isSignError(codeSignMap))
            throw new RuntimeException("越权");

        filterChain.doFilter(servletRequest, servletResponse);
    }

    private Map<String, String> findInputCodeSignMap(HttpServletRequest request) {
        Map<String,String> codeSignMap = new HashMap<>();
        request.getParameterMap().forEach((k,v) -> {
            if (!k.endsWith(SignUtils.signSuffix())) return;
            String codeParamName = k.substring(0,k.indexOf(SignUtils.signSuffix()));
            codeSignMap.put(
                    StringUtils.isEmpty(request.getParameter(codeParamName)) ? "1" : request.getParameter(codeParamName),
                    StringUtils.isEmpty(v) ? "" : v[0]
            );
        });
        return codeSignMap;
    }

    private boolean isJsonReq(HttpServletRequest request) {
        return !StringUtils.isEmpty(request.getContentType()) && "application/json".equalsIgnoreCase(request.getContentType());
    }

    @Override
    public void destroy() {

    }
}
